from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from carts.serializers import CartsSerializers, CartSerializers, CartsDeleteSerializers, CartsSelectionSerializers
from django_redis import get_redis_connection
import pickle, base64
from carts.utils import merge_cart_cookie_to_redis

# Create your views here.
from goods.models import SKU


class CartsView(APIView):
    def perform_authentication(self, request):
        pass

    def post(self, request):

        # 数据获取
        data = request.data

        # 数据验证
        ser = CartsSerializers(data=data)
        ser.is_valid()
        sku_id = ser.validated_data['sku_id']
        count = ser.validated_data['count']
        selected = ser.validated_data['selected']

        # 用户登陆状态判断

        try:
            user = request.user

        except:
            user = None

        if user is not None:
            # 用户已登陆 保存redis
            # 建立连接
            conn = get_redis_connection('cart')
            # 保存sku_id和count
            conn.hincrby('cart_%s' % user.id, sku_id, count)
            # 保存选中状态
            if selected:
                conn.sadd('cart_selected_%s' % user.id, sku_id)

            return Response(ser.data)

        else:
            # 用户未登录， 保存在cookie
            # 获取cookie
            cart_cookie = request.COOKIES.get('cart_cookie')
            if cart_cookie:
                # 解密
                cart = pickle.loads(base64.b64decode(cart_cookie.encode()))
            else:
                cart = {}

            # 判断sku_id数据之前是否存储过
            sku = cart.get(sku_id)
            if sku:
                count += int(sku['count'])

            cart[sku_id] = {
                'count': count,
                'selected': selected
            }

            # 结果返回
            # 加密数据
            cart_cookie = base64.b64encode(pickle.dumps(cart))
            response = Response(ser.data)
            response.set_cookie('cart_cookie', cart_cookie, 60 * 60 * 24 * 7)

            print('商品添加成功')

            return response

    def get(self, request):
        # 用户登陆状态判断
        try:
            user = request.user
        except:
            user = None

        if user is not None:
            # 用户已登陆， 从redis获取数据、
            # 建立连接
            conn = get_redis_connection('cart')
            # 获取sku_id和count
            cart_conut = conn.hgetall('cart_%s' % user.id)  # hgetall:返回 key 指定的哈希集中所有的字段和值
            # 获取选中状态sku_id
            cart_selected = conn.smembers('cart_selected_%s' % user.id)

            # 构造数据
            cart = {}
            for sku_id, count in cart_conut.items():
                cart[int(sku_id)] = {
                    'count': int(count),
                    'selected': sku_id in cart_selected
                }
        else:
            # 用户未登录， 保存在cookie
            # 获取cookie
            cart_cookie = request.COOKIES.get('cart_cookie')
            if cart_cookie:
                # 解密
                cart = pickle.loads(base64.b64decode(cart_cookie.encode()))
            else:
                cart = {}

        # 查询商品
        # sku_list = []
        sku_list = SKU.objects.filter(id__in=cart.keys())

        # 商品对象添加字段属性
        for sku in sku_list:
            sku.count = cart[sku.id]['count']
            sku.selected = cart[sku.id]['selected']

        ser = CartSerializers(sku_list, many=True)
        response = Response(ser.data)

        return response

    def put(self, request):
        # 数据获取
        data = request.data

        # 数据验证
        ser = CartsSerializers(data=data)
        ser.is_valid()
        sku_id = ser.validated_data['sku_id']
        count = ser.validated_data['count']
        selected = ser.validated_data['selected']

        try:
            user = request.user

        except:
            user = None

        if user is not None:
            # 用户已登陆 更新redis
            # 建立连接
            conn = get_redis_connection('cart')
            # 更新sku_id和count
            conn.hset('cart_%s' % user.id, sku_id, count)
            # 保存选中状态
            if selected:
                conn.sadd('cart_selected_%s' % user.id, sku_id)

            print('%s购物车修改成功' % user.username)
            return Response(ser.data)

        else:
            # 用户未登录， 更新在cookie
            # 获取cookie 判断cookie以前是否存储过
            cart_cookie = request.COOKIES.get('cart_cookie')
            if cart_cookie:
                # 解密
                cart = pickle.load(base64.b64decode(cart_cookie.encode()))
            else:
                cart = {}

            # 结果返回
            # 加密数据
            cart_cookie = base64.b64encode(pickle.dumps(cart).decode())
            response = Response(ser.data)

            response.set_cookie('cart_cookie', cart_cookie, 60 * 60 * 24 * 7)


            return response

    def delete(self, request):
        # 数据获取
        data = request.data

        # 数据验证
        ser = CartsDeleteSerializers(data=data)
        ser.is_valid()
        sku_id = ser.validated_data['sku_id']

        # 用户登陆状态判断
        try:
            user = request.user
        except:
            user = None

        if user is not None:
            # 用户已登陆 删除redis数据
            # 建立数据
            conn = get_redis_connection('cart')
            # 删除sku_id和count
            conn.hdel('cart_%s'%user.id, sku_id)
            # 删除选中状态
            conn.srem('cart_selected_%s'%user.id, sku_id)
            return Response(status=200)

        else:
            # 用户未登录 删除cookie
            # 获取cookie,判断cookie以前是否存储过
            cart_cookie = request.COOKIES.get('cart_cookie')
            # 生成响应对象
            response = Response(status=200)
            if cart_cookie:
                # 解密
                cart = pickle.loads(base64.b64decode(cart_cookie.encode()))

                # 删除数据
                if sku_id in cart.keys():
                    del cart[sku_id]

                # 结果返回
                # 加密数据
                cart_cookie = base64.b64decode(pickle.dumps(cart)).decode()

                response.set_cookie('cart_cookie', cart_cookie, 60*60*24*7)

            return response


class CartsSelectionView(APIView):

    def perform_authentication(self, request):
        pass

    def put(self, request):

        # 数据获取
        data = request.data

        # 数据验证
        ser = CartsSelectionSerializers(data=data)
        ser.is_valid()


        selected = ser.validated_data['selected']


        # 用户登陆状态判断：
        try:
            user = request.user
        except:
            user = None

        if user is not None:
            # 用户已登陆 更新redis
            # 建立链接
            conn = get_redis_connection('cart')
            sku_id_count = conn.hgetall('cart_%s'%user.id)
            sku_id_list = sku_id_count.keys()
            # 更新选中状态
            if selected:
                conn.sadd('cart_selected_%s' %user.id, *sku_id_list)
            else:
                # 将所有sku_id从集合当中移除
                conn.srem('cart_selected_%s' %user.id, *sku_id_list)

            print('购物车合并成功')
            return Response(ser.data)

        else:
            # 用户未登录， 更新在cookie
            # 获取cookie 判断cookie以前是否存储过
            cart_cookie = request.COOKIES.get('cart_cookie')
            response = Response(ser.data)
            if cart_cookie:
                # 解密
                cart = pickle.load(base64.b64decode(cart_cookie.encode()))

                # 将字典当中的状态值进行更新
                for sku_id in cart.keys():
                    cart[sku_id]['selected']=selected

                # 结果返回
                # 加密数据
                cart_cookie = base64.b64encode(pickle.dumps(cart).decode())
                response = Response(ser.data)

                response.set_cookie('cart_cookie', cart_cookie, 60 * 60 * 24 * 7)

            print('购物车合并成功')
            return response


